#region "Copyright (C) Lenny Granovsky. 2005-2013"
//This program is free software distribute under the terms of the GNU General Public License as published by
//the Free Software Foundation. Please read AssemblyInfo.cs file for more information.
#endregion

using System;
using System.Collections.Generic;
using System.Text;
using System.Configuration;
using System.Collections.Specialized;
using System.Xml;
using System.Security.Cryptography;
using System.Web;

namespace Web.Enhancements.Rest
{
    internal static class WebRestClassConfigurationExtension 
    {
        internal static bool Contains(this Dictionary<string, WebRestClassConfiguration> list, string classFullName, string classAssemblyName)
        {
            return Contains(list, classFullName, classAssemblyName, false);
        }

        internal static bool Contains(this Dictionary<string, WebRestClassConfiguration> list, string classFullName, string classAssemblyName, bool ignoreCase)
        {
            foreach (WebRestClassConfiguration conf in list.Values)
            {
                if (conf.IsSameClass(classFullName, classAssemblyName, ignoreCase))
                    return true;
            }
            return false;
        }

        internal static WebRestClassConfiguration Find(this Dictionary<string, WebRestClassConfiguration> list, string classFullName, string classAssemblyName)
        {
            return Find(list, classFullName, classAssemblyName, false);
        }

        internal static WebRestClassConfiguration Find(this Dictionary<string, WebRestClassConfiguration> list, string classFullName, string classAssemblyName, bool ignoreCase)
        {
            foreach (WebRestClassConfiguration conf in list.Values)
            {
                if (conf.IsSameClass(classFullName, classAssemblyName, ignoreCase))
                    return conf;
            }
            return null;
        }

        internal static WebRestClassConfiguration Find(this Dictionary<string, WebRestClassConfiguration> list, string alias)
        {
            foreach (WebRestClassConfiguration conf in list.Values)
            {
                if (string.Compare(conf.AliasName, alias, true) == 0)
                    return conf;
            }
            return null;
        }
    }

    [Serializable()]
    internal class WebRestClassConfiguration
	{
        private string aliasName;
        /// <summary>
        /// Type (class) alias name to use within JS Client.
        /// </summary>
        public string AliasName
        {
            get
            {
                return this.aliasName;
            }
            set
            {
                this.aliasName = value;
                if (value.IndexOf('.') > 0)
                    this.aliasNamespace = value.Substring(0, value.LastIndexOf("."));
                else this.aliasNamespace = "";
            }
        }
        /// <summary>
        /// Type (class) Full Name, includes namespace.
        /// </summary>
        public string FullName { get; set; }
        /// <summary>
        /// Type (class) Full Qualified Name, including namespace and assembly name.
        /// </summary>
        public string FullQualifiedName { get; set; }

        private string assemblyName;
        /// <summary>
        /// Type (class) Assembly name.
        /// </summary>
        public string AssemblyName
        {
            get
            {
                return this.assemblyName;
            }
            set
            {
                this.assemblyName = value;
                if (value.Length == 0)
                    this.assemblyNameForEvaluation = "";
                else
                    this.assemblyNameForEvaluation = value + ",";
            }
        }

        private string aliasNamespace;
        /// <summary>
        /// Type (class) alias Namespace to use within JS Client.
        /// </summary>
        public string AliasNamespace
        {
            get
            {
                return this.aliasNamespace;
            }
        }

        private string assemblyNameForEvaluation;
        /// <summary>
        /// Gets true if namespace should be used within JS Client.
        /// </summary>
        public bool IncludeNamespaceOnClientSide
        {
            get
            {
                return (this.aliasNamespace.Length > 0);
            }
        }
        /// <summary>
        /// Gets or sets boolean value indicated if "." character in namespace should be replaced with "/" path separator when url is formed.
        /// </summary>
        public bool ReplaceDotWithPathSeparator { get; set; }

        public WebRestClassConfiguration(string classFullName, string classAssemblyName)
        {
            this.ReplaceDotWithPathSeparator = true;
            this.FullName = classFullName;
            this.AliasName = classFullName;
            this.AssemblyName = classAssemblyName;
            this.FullQualifiedName = classAssemblyName.Length > 0 ? string.Format("{0}, {1}", classFullName, classAssemblyName) : classFullName;
        }

        public WebRestClassConfiguration()
		{
            this.ReplaceDotWithPathSeparator = true;
            this.AliasName = "";
			this.AssemblyName = "";
            this.FullName = "";
            this.FullQualifiedName = "";
        }

        public bool IsSameClass(string fullName)
        {
            return this.FullName == fullName;
        }

        public bool IsSameClass(string fullName, string assemblyName)
        {
            if (this.FullName != fullName)
                return false;
            if (this.AssemblyName == assemblyName)
                return true;
            if (assemblyName.StartsWith(this.assemblyNameForEvaluation))
                return true;
            return false;
        }

        public bool IsSameClass(string fullName, bool ignoreCase)
        {
            if (!ignoreCase)
                return this.IsSameClass(fullName);
            return (string.Compare(this.FullName, fullName, true) == 0);
        }

        public bool IsSameClass(string fullName, string assemblyName, bool ignoreCase)
        {
            if (!ignoreCase)
                return this.IsSameClass(fullName, assemblyName);

            if (string.Compare(this.FullName, fullName, true) != 0)
                return false;
            if (string.Compare(this.AssemblyName, assemblyName, true) == 0)
                return true;
            if (assemblyName.ToLower().StartsWith(this.assemblyNameForEvaluation.ToLower()))
                return true;
            return false;
        }
    }
}
